//
// Created by admin on 2022/9/6.
//

#ifndef LEARN_OPENCV_MACROSDEAL_HPP
#define LEARN_OPENCV_MACROSDEAL_HPP
/*专门用作宏处理*/
/*后续args使用括号包裹起来，保证入参都是(...)*/
/*同型宏模板只会解析最外层（宏无法处理递归）*/
#define JOIN_IMPL(a, b) a##b
#define JOIN(a, b) JOIN_IMPL(a,b)

#define UNION(a, b) a b

#define CONCAT_IMPL1(a, b) a##b
#define CONCAT_IMPL2(a, b) CONCAT_IMPL1(a,b
#define CONCAT_IMPL3(a, b) CONCAT_IMPL2(a,b)
#define CONCAT_IMPL4(a, b) CONCAT_IMPL3(a,b)
#define CONCAT_IMPL5(a, b) CONCAT_IMPL4(a,b)
#define CONCAT_IMPL6(a, b) CONCAT_IMPL5(a,b)
#define CONCAT(a, b) CONCAT_IMPL6(a,b)

#define RESULT(x) x
#define CALL_TYPE(fn) fn
#define CALL(fn, ...) RESULT(fn(__VA_ARGS__))
#define CALL_D(fn, args) RESULT(fn args)
#define CALL_D1(fn, a, args) CALL_D(fn,(a,args))

// (e1, e2, e3, ...) => e1
#define GET_HEAD_IMPL(_1, ...) _1
// GET_HEAD_IMPL(1,2,3) args = (1,2,3)
#define GET_HEAD(args) CALL_D(GET_HEAD_IMPL, args)

// (e1, e2, e3, ...) => (e2, e3, ...)
#define GET_TAIL_IMPL(_1, ...) __VA_ARGS__
#define GET_TAIL(args) CALL_D(GET_TAIL_IMPL, args)

#define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _n, ...) _n
#define COUNT_ARGS(X...) __COUNT_ARGS(, ##X, 16 , 15 , 14 , 13 , 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

#define __COUNT_ARGS_1(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _n, ...) _n
#define COUNT_ARGS_1(X...) __COUNT_ARGS_1(, ##X, 16 , 15 , 14 , 13 , 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)


/*恒定入参处理*/
#define LOOP_DEAL_C_0(callType, fn, ...)                                                CALL_TYPE(callType)(fn,0 ,##__VA_ARGS__)
#define LOOP_DEAL_C_1(callType, fn, ...) LOOP_DEAL_C_0( callType, fn,##__VA_ARGS__) COMA CALL_TYPE(callType)(fn,1 ,##__VA_ARGS__)
#define LOOP_DEAL_C_2(callType, fn, ...) LOOP_DEAL_C_1( callType, fn,##__VA_ARGS__) COMA CALL_TYPE(callType)(fn,2 ,##__VA_ARGS__)
#define LOOP_DEAL_C_3(callType, fn, ...) LOOP_DEAL_C_2( callType, fn,##__VA_ARGS__) COMA CALL_TYPE(callType)(fn,3 ,##__VA_ARGS__)
#define LOOP_DEAL_C_4(callType, fn, ...) LOOP_DEAL_C_3( callType, fn,##__VA_ARGS__) COMA CALL_TYPE(callType)(fn,4 ,##__VA_ARGS__)
#define LOOP_DEAL_C_5(callType, fn, ...) LOOP_DEAL_C_4( callType, fn,##__VA_ARGS__) COMA CALL_TYPE(callType)(fn,5 ,##__VA_ARGS__)
#define LOOP_DEAL_C_6(callType, fn, ...) LOOP_DEAL_C_5( callType, fn,##__VA_ARGS__) COMA CALL_TYPE(callType)(fn,6 ,##__VA_ARGS__)
#define LOOP_DEAL_C_7(callType, fn, ...) LOOP_DEAL_C_6( callType, fn,##__VA_ARGS__) COMA CALL_TYPE(callType)(fn,7 ,##__VA_ARGS__)
#define LOOP_DEAL_C_8(callType, fn, ...) LOOP_DEAL_C_7( callType, fn,##__VA_ARGS__) COMA CALL_TYPE(callType)(fn,8 ,##__VA_ARGS__)
#define LOOP_DEAL_C_9(callType, fn, ...) LOOP_DEAL_C_8( callType, fn,##__VA_ARGS__) COMA CALL_TYPE(callType)(fn,9 ,##__VA_ARGS__)
#define LOOP_DEAL_C_10(callType, fn, ...) LOOP_DEAL_C_9( callType, fn,##__VA_ARGS__) COMA CALL_TYPE(callType)(fn,10,##__VA_ARGS__)
#define LOOP_DEAL_C_11(callType, fn, ...) LOOP_DEAL_C_10(callType, fn,##__VA_ARGS__) COMA CALL_TYPE(callType)(fn,11,##__VA_ARGS__)
#define LOOP_DEAL_C_12(callType, fn, ...) LOOP_DEAL_C_11(callType, fn,##__VA_ARGS__) COMA CALL_TYPE(callType)(fn,12,##__VA_ARGS__)
#define LOOP_DEAL_C_13(callType, fn, ...) LOOP_DEAL_C_12(callType, fn,##__VA_ARGS__) COMA CALL_TYPE(callType)(fn,13,##__VA_ARGS__)
#define LOOP_DEAL_C_14(callType, fn, ...) LOOP_DEAL_C_13(callType, fn,##__VA_ARGS__) COMA CALL_TYPE(callType)(fn,14,##__VA_ARGS__)
#define LOOP_DEAL_C_15(callType, fn, ...) LOOP_DEAL_C_14(callType, fn,##__VA_ARGS__) COMA CALL_TYPE(callType)(fn,15,##__VA_ARGS__)
#define LOOP_DEAL_C_16(callType, fn, ...) LOOP_DEAL_C_15(callType, fn,##__VA_ARGS__) COMA CALL_TYPE(callType)(fn,16,##__VA_ARGS__)

/*可变迭代参数处理*/
#define LOOP_DEAL_V_1(fn, args) CALL_D(fn,args)
#define LOOP_DEAL_V_2(fn, args) fn(GET_HEAD(args)) COMA LOOP_DEAL_V_1(  fn, (GET_TAIL(args)))
#define LOOP_DEAL_V_3(fn, args) fn(GET_HEAD(args)) COMA LOOP_DEAL_V_2(  fn, (GET_TAIL(args)))
#define LOOP_DEAL_V_4(fn, args) fn(GET_HEAD(args)) COMA LOOP_DEAL_V_3(  fn, (GET_TAIL(args)))
#define LOOP_DEAL_V_5(fn, args) fn(GET_HEAD(args)) COMA LOOP_DEAL_V_4(  fn, (GET_TAIL(args)))
#define LOOP_DEAL_V_6(fn, args) fn(GET_HEAD(args)) COMA LOOP_DEAL_V_5(  fn, (GET_TAIL(args)))
#define LOOP_DEAL_V_7(fn, args) fn(GET_HEAD(args)) COMA LOOP_DEAL_V_6(  fn, (GET_TAIL(args)))
#define LOOP_DEAL_V_8(fn, args) fn(GET_HEAD(args)) COMA LOOP_DEAL_V_7(  fn, (GET_TAIL(args)))
#define LOOP_DEAL_V_9(fn, args) fn(GET_HEAD(args)) COMA LOOP_DEAL_V_8(  fn, (GET_TAIL(args)))
#define LOOP_DEAL_V_10(fn, args) fn(GET_HEAD(args)) COMA LOOP_DEAL_V_9(  fn, (GET_TAIL(args)))
#define LOOP_DEAL_V_11(fn, args) fn(GET_HEAD(args)) COMA LOOP_DEAL_V_10( fn, (GET_TAIL(args)))
#define LOOP_DEAL_V_12(fn, args) fn(GET_HEAD(args)) COMA LOOP_DEAL_V_11( fn, (GET_TAIL(args)))
#define LOOP_DEAL_V_13(fn, args) fn(GET_HEAD(args)) COMA LOOP_DEAL_V_12( fn, (GET_TAIL(args)))
#define LOOP_DEAL_V_14(fn, args) fn(GET_HEAD(args)) COMA LOOP_DEAL_V_13( fn, (GET_TAIL(args)))
#define LOOP_DEAL_V_15(fn, args) fn(GET_HEAD(args)) COMA LOOP_DEAL_V_14( fn, (GET_TAIL(args)))
#define LOOP_DEAL_V_16(fn, args) fn(GET_HEAD(args)) COMA LOOP_DEAL_V_15( fn, (GET_TAIL(args)))

/*tuple展开*/
#define GET_TUPLE_IMPL(n, tp) get<n>(tp)
#define TupleExpand(n, ...) LOOP_DEAL_C_##n(CALL,GET_TUPLE_IMPL,__VA_ARGS__)
/*index展开*/
#define INDEX_IMPL(n) n
#define IndexExpand(n, ...) LOOP_DEAL_C_##n(CALL,INDEX_IMPL,##__VA_ARGS__)

/*迭代展开*/
#define WITH_NAME(arg) {STRING_FY(arg),arg}
#define IT_NAME_EXPAND(...) JOIN(LOOP_DEAL_V_, COUNT_ARGS(__VA_ARGS__))(WITH_NAME,(__VA_ARGS__))


#define STRING_FY_IMPL(arg) #arg
#define STRING_FY(arg) STRING_FY_IMPL(arg)
#define Num(n) n



/*控制台颜色*/

#define DEBUG_CODE      02
#define BLACK_CODE      30
#define RED_CODE        31
#define GREEN_CODE      32
#define YELLOW_CODE     33
#define BLUE_CODE       34
#define PURPLE_CODE     35
#define DEEP_GREEN_CODE 36
#define WHITE_CODE      37
/*特殊符号可以省去##, 用以拼接token*/
#define FRONT_COLOR_IMPL(n) \x1b[n##m
#define FRONT_COLOR(n) FRONT_COLOR_IMPL(n)
#define FRONT_COLOR_STR(n) STRING_FY(CALL_D(FRONT_COLOR_IMPL,(n)))

#define ANSI_RESET_IMPL \x1b[0m
#define ANSI_RESET ANSI_RESET_IMPL
#define ANSI_RESET_STR STRING_FY(ANSI_RESET_IMPL)

#define OUT_PUT <<
#define FRONT_COLOR_STR_U(t) UNION(FRONT_COLOR_STR(t),OUT_PUT)
#define ANSI_RESET_STR_U UNION(OUT_PUT,ANSI_RESET_STR)

#define ANSI_BLACK(s)          FRONT_COLOR_STR_U(BLACK_CODE) s ANSI_RESET_STR_U
#define ANSI_RED(s)            FRONT_COLOR_STR_U(RED_CODE) s ANSI_RESET_STR_U
#define ANSI_GREEN(s)          FRONT_COLOR_STR_U(GREEN_CODE) s ANSI_RESET_STR_U
#define ANSI_YELLOW(s)         FRONT_COLOR_STR_U(YELLOW_CODE) s ANSI_RESET_STR_U
#define ANSI_BLUE(s)           FRONT_COLOR_STR_U(BLUE_CODE) s ANSI_RESET_STR_U
#define ANSI_PURPLE(s)         FRONT_COLOR_STR_U(PURPLE_CODE) s ANSI_RESET_STR_U
#define ANSI_DEEP_GREEN(s)     FRONT_COLOR_STR_U(DEEP_GREEN_CODE) s ANSI_RESET_STR_U
#define ANSI_WHITE(s)          FRONT_COLOR_STR_U(WHITE_CODE) s ANSI_RESET_STR_U
#define ANSI_DBG(s)            FRONT_COLOR_STR_U(DEBUG_CODE) s ANSI_RESET_STR_U

#define COMA ,

#define SPACE


/*用于可变长度参数迭代序号处理*/
namespace INDEX_TEMPLATE {
    template<int N>
    struct Index {
    };

    template<int... N>
    struct Seq {
    };

#define INDEX_SEQ(n) template<> struct Index<n> : Seq<IndexExpand(n)> {};
#define INDEX_SEQ_NEG(n) template<> struct Index<n> : Seq<> {};

    /*结束处理*/
    INDEX_SEQ_NEG(-1)
    INDEX_SEQ_NEG(-2)
    INDEX_SEQ_NEG(-3)
    INDEX_SEQ_NEG(-4)
    INDEX_SEQ_NEG(-5)
    INDEX_SEQ_NEG(-6)
    INDEX_SEQ_NEG(-7)
    INDEX_SEQ_NEG(-8)
    INDEX_SEQ_NEG(-9)
    INDEX_SEQ_NEG(-10)
    INDEX_SEQ_NEG(-11)
    INDEX_SEQ_NEG(-12)
    INDEX_SEQ_NEG(-13)
    INDEX_SEQ_NEG(-14)
    INDEX_SEQ_NEG(-15)
    /*特化16组（最多支持16长度的序列处理）*/
    INDEX_SEQ(0)
    INDEX_SEQ(1)
    INDEX_SEQ(2)
    INDEX_SEQ(3)
    INDEX_SEQ(4)
    INDEX_SEQ(5)
    INDEX_SEQ(6)
    INDEX_SEQ(7)
    INDEX_SEQ(8)
    INDEX_SEQ(9)
    INDEX_SEQ(10)
    INDEX_SEQ(11)
    INDEX_SEQ(12)
    INDEX_SEQ(13)
    INDEX_SEQ(14)
    INDEX_SEQ(15)

}

#endif //LEARN_OPENCV_MACROSDEAL_HPP
